﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed
#pragma once
#include "GcmpModelInterface.h"
#include "IDbObject.h"
#include "RegenDataId.h"

namespace gcmp
{
    class IDocument;
    class IElement;
    class IParameter;
    class Coordinate3d;
    /// \brief 关联平面定位基类
    class GCMP_MODEL_INTERFACE_EXPORT IPositionAssociatedPlane : public IDbObject
    {
        DEFINE_CAST_DERIVED(gcmp::IPositionAssociatedPlane, gcmp::IDbObject)

    public:
        /// \brief 克隆关联平面定位对象
        /// \return 克隆后的关联平面定位对象
        virtual OwnerPtr<IPositionAssociatedPlane> Clone() const = 0;

        /// \brief 设置该行为所属Element
        /// \param pOwnerElement 所属Element
        /// \return bool
        virtual bool SetOwnerElement(IElement* pOwnerElement) = 0;

        /// \brief 获得该行为所属的Element
        /// \return 所属的Element
        virtual IElement* GetOwnerElement() = 0;

        /// \brief 获得该行为所属的Element
        /// \return 所属的Element
        virtual const IElement* GetOwnerElement() const = 0;

        /// \brief 得到基准平面坐标系
        /// \return 基准平面坐标系
        virtual Coordinate3d GetBasePlaneCoordinate3d() const = 0;

        /// \brief 得到基准平面对象id
        /// \return 基准平面对象id
        virtual ElementId GetBasePlaneElementId() const = 0;

        /// \brief 设置基准平面对象id
        /// \param id 基准平面对象id
        /// \return 返回true表示成功设置，否则表示失败
        virtual bool SetBasePlaneElementId(const ElementId &id) = 0;

        /// \brief 得到基准平面偏移量
        /// \return 基准平面偏移量
        virtual double GetBasePlaneOffset() const = 0;

        /// \brief 设置基准平面偏移量
        /// \param value 偏移量
        /// \return 返回true表示成功设置，否则表示失败
        virtual bool SetBasePlaneOffset(double value) = 0;

        /// \brief 得到基准平面高度值
        /// \return 基准平面标高度值，若关联平面是标高，则为标高值。
        virtual double GetBasePlaneHeight() const = 0;

        /// \brief 报出参数定义索引集合
        /// \param pParameterDefinitionIds 参数定义索引集合
        /// \return void
        virtual void ReportParameterDefinitions(std::vector<int>* pParameterDefinitionIds) const = 0;

        /// \brief 根据参数定义索引得到原生参数
        /// \param parameterDefinitionId 参数定义索引
        /// \return 参数
        virtual OwnerPtr<IParameter> GetNativeParameter(int parameterDefinitionId) const = 0;

        /// \brief 设置原生参数
        /// \param parameter 参数
        /// \param errorMsg 指针有效表示输出错误信息，否则不输出错误信息
        /// \return 返回true表示成功设置，否则表示失败 
        virtual bool SetNativeParameter(const IParameter *parameter, std::wstring* errorMsg = nullptr) = 0;

        /// \brief 判断是否为定位参数
        /// \param parameterDefinitionId
        /// \return 返回true表示是个定位参数，否则表示不是定位参数
        virtual bool IsPositionParameter(int parameterDefinitionId) const = 0;

        /// \brief 判断参数是否允许被修改
        /// \param parameterDefinitionId
        /// \return 返回true表示是参数允许修改，否则表示不允许修改
        virtual bool IsParameterModifiable(int parameterDefinitionId) const = 0;

        /// \brief 根据定位参数id,获取相应的关联更新变化Id
        /// \param parameterDefinitionId 参数id
        /// \param rdId  [out]关联更新变化Id
        /// \return 返回true表示是成功更新，否则表示失败
        virtual bool GetRegenDataId(int parameterDefinitionId, RegenDataId& rdId) const = 0;
    public:
        /// \brief 获取顶部关联平面的Id
        /// 
        /// 当且仅当关联平面为IPositionTwoAssociatedPlanes 或 IPositionTwoAssociatedPlanesWithFourOffsets 时, 该接口才有意义
        /// \see IPositionTwoAssociatedPlanesWithFourOffsets and \see IPositionTwoAssociatedPlanes
        /// \param pElement 需要获取的顶部关联平面的Element
        /// \return ElementId  顶部关联平面ID, 获取不到则返回ElementId::INVAILD;
        static ElementId GetTopAssociatedPlaneId(const IElement* pElement);

        /// \brief 设置顶部关联平面的Id
        /// 
        /// 当且仅当关联平面为IPositionTwoAssociatedPlanes 或 IPositionTwoAssociatedPlanesWithFourOffsets 时, 该接口才有意义
        /// \see IPositionTwoAssociatedPlanesWithFourOffsets and \see IPositionTwoAssociatedPlanes
        /// \param pElement 需要设置顶部关联平面的Element
        /// \return bool 设置成功则返回true, 否则返回false;
        static bool SetTopAssociatedPlaneId(IElement* pElement, const ElementId& planeId);

        /// \brief 获取底部关联平面(基准面)偏移量
        /// 
        /// 单个带有起点终点的关联平面下：
        ///     允许设置面的高度偏移量时， 则获取的为面的高度偏移量， 否则为起点高度偏移
        /// 其他类型均为基准面或者底面的高度偏移量
        ///
        /// \param 需要获取基准面高度偏移的element
        /// \param [out] 传出参数，高度偏移值
        /// \return bool true 获取成功， false 获取失败
        static bool GetBottomPlaneHeightOffset(const IElement* pElement, double& offset);

        /// \brief 设置底部关联平面(基准面)偏移量
        ///
        /// 单个带有起点终点的关联平面下：
        ///     允许设置面的高度偏移量时， 则设置的为面的高度偏移量， 否则为起点高度偏移量
        /// 其他类型均为基准面或者底面的高度偏移量
        ///
        /// \param 需要设置基准面高度偏移的element
        /// \param 待设置起始高度偏移值
        /// \return bool 设置成功返回true, 失败返回false
        static bool SetBottomPlaneHeightOffset(IElement* pElement, double dVal);

        /// \brief 获取顶部关联平面高度偏移
        /// 
        /// 当且仅当关联平面为IPositionTwoAssociatedPlanes 或 IPositionTwoAssociatedPlanesWithFourOffsets 时, 该接口才有意义
        /// \see IPositionTwoAssociatedPlanesWithFourOffsets and \see IPositionTwoAssociatedPlanes
        /// \param 需要置顶部关联平面高度偏移的element
        /// \param [out] 传出参数， 起始高度偏移值
        /// \return bool true 获取成功， false 获取失败
        static bool GetTopPlaneHeightOffset(const IElement* pElement, double& offset);

        /// \brief 设置顶部关联平面高度偏移
        /// 
        /// 当且仅当关联平面为IPositionTwoAssociatedPlanes 或 IPositionTwoAssociatedPlanesWithFourOffsets 时, 该接口才有意义
        /// \see IPositionTwoAssociatedPlanesWithFourOffsets and \see IPositionTwoAssociatedPlanes
        /// \param 需要设置顶部关联平面高度偏移的element
        /// \param 待设置的偏移值
        /// \return  bool 设置成功返回true， 否则返回false
        static bool SetTopPlaneHeightOffset(IElement* pElement, double dVal);
    };
}



